#include "bookmarkmanager.h"
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlError>
#include <QStandardPaths>
#include <QDir>
#include <QDateTime>
#include <QApplication>
#include <QDebug>

BookmarkManager::BookmarkManager(QObject *parent)
    : QObject(parent)
    , m_initialized(false)
{
}

BookmarkManager::~BookmarkManager()
{
    if (m_database.isOpen()) {
        m_database.close();
    }
}

bool BookmarkManager::initialize(const QString &databasePath)
{
    if (m_initialized) {
        return true;
    }
    
    m_databasePath = databasePath;
    if (m_databasePath.isEmpty()) {
        m_databasePath = getDefaultDatabasePath();
    }
    
    // 确保目录存在
    QFileInfo fileInfo(m_databasePath);
    QDir dir;
    if (!dir.exists(fileInfo.absolutePath())) {
        if (!dir.mkpath(fileInfo.absolutePath())) {
            qWarning() << "Failed to create directory for bookmark database:" << fileInfo.absolutePath();
            return false;
        }
    }
    
    // 创建数据库连接
    m_database = QSqlDatabase::addDatabase("QSQLITE", "bookmark_connection");
    m_database.setDatabaseName(m_databasePath);
    
    if (!m_database.open()) {
        qWarning() << "Failed to open bookmark database:" << m_database.lastError().text();
        return false;
    }
    
    // 创建表
    if (!createTables()) {
        return false;
    }
    
    m_initialized = true;
    return true;
}

bool BookmarkManager::addBookmark(const QString &name, const QString &query, const QString &databaseName)
{
    if (!m_initialized || name.trimmed().isEmpty() || query.trimmed().isEmpty()) {
        return false;
    }
    
    QSqlQuery sqlQuery(m_database);
    sqlQuery.prepare("INSERT INTO bookmarks (name, query, created, database_name) VALUES (?, ?, ?, ?)");
    sqlQuery.addBindValue(name);
    sqlQuery.addBindValue(query);
    sqlQuery.addBindValue(QDateTime::currentDateTime());
    sqlQuery.addBindValue(databaseName);
    
    if (!sqlQuery.exec()) {
        qWarning() << "Failed to add bookmark:" << sqlQuery.lastError().text();
        return false;
    }
    
    emit bookmarksChanged();
    return true;
}

bool BookmarkManager::removeBookmark(int id)
{
    if (!m_initialized || id <= 0) {
        return false;
    }
    
    QSqlQuery sqlQuery(m_database);
    sqlQuery.prepare("DELETE FROM bookmarks WHERE id = ?");
    sqlQuery.addBindValue(id);
    
    if (!sqlQuery.exec()) {
        qWarning() << "Failed to remove bookmark:" << sqlQuery.lastError().text();
        return false;
    }
    
    emit bookmarksChanged();
    return true;
}

bool BookmarkManager::updateBookmark(int id, const QString &name, const QString &query)
{
    if (!m_initialized || id <= 0 || name.trimmed().isEmpty() || query.trimmed().isEmpty()) {
        return false;
    }
    
    QSqlQuery sqlQuery(m_database);
    sqlQuery.prepare("UPDATE bookmarks SET name = ?, query = ? WHERE id = ?");
    sqlQuery.addBindValue(name);
    sqlQuery.addBindValue(query);
    sqlQuery.addBindValue(id);
    
    if (!sqlQuery.exec()) {
        qWarning() << "Failed to update bookmark:" << sqlQuery.lastError().text();
        return false;
    }
    
    emit bookmarksChanged();
    return true;
}

QList<BookmarkItem> BookmarkManager::getBookmarks() const
{
    QList<BookmarkItem> result;
    
    if (!m_initialized) {
        return result;
    }
    
    QSqlQuery sqlQuery(m_database);
    sqlQuery.prepare("SELECT id, name, query, created, database_name FROM bookmarks ORDER BY created DESC");
    
    if (!sqlQuery.exec()) {
        qWarning() << "Failed to retrieve bookmarks:" << sqlQuery.lastError().text();
        return result;
    }
    
    while (sqlQuery.next()) {
        BookmarkItem item;
        item.id = sqlQuery.value(0).toInt();
        item.name = sqlQuery.value(1).toString();
        item.query = sqlQuery.value(2).toString();
        item.created = sqlQuery.value(3).toDateTime();
        item.databaseName = sqlQuery.value(4).toString();
        result.append(item);
    }
    
    return result;
}

QList<BookmarkItem> BookmarkManager::searchBookmarks(const QString &searchTerm) const
{
    QList<BookmarkItem> result;
    
    if (!m_initialized || searchTerm.isEmpty()) {
        return result;
    }
    
    QSqlQuery sqlQuery(m_database);
    sqlQuery.prepare("SELECT id, name, query, created, database_name FROM bookmarks WHERE name LIKE ? OR query LIKE ? ORDER BY created DESC");
    sqlQuery.addBindValue("%" + searchTerm + "%");
    sqlQuery.addBindValue("%" + searchTerm + "%");
    
    if (!sqlQuery.exec()) {
        qWarning() << "Failed to search bookmarks:" << sqlQuery.lastError().text();
        return result;
    }
    
    while (sqlQuery.next()) {
        BookmarkItem item;
        item.id = sqlQuery.value(0).toInt();
        item.name = sqlQuery.value(1).toString();
        item.query = sqlQuery.value(2).toString();
        item.created = sqlQuery.value(3).toDateTime();
        item.databaseName = sqlQuery.value(4).toString();
        result.append(item);
    }
    
    return result;
}

BookmarkItem BookmarkManager::getBookmarkById(int id) const
{
    BookmarkItem item;
    
    if (!m_initialized || id <= 0) {
        return item;
    }
    
    QSqlQuery sqlQuery(m_database);
    sqlQuery.prepare("SELECT id, name, query, created, database_name FROM bookmarks WHERE id = ?");
    sqlQuery.addBindValue(id);
    
    if (!sqlQuery.exec()) {
        qWarning() << "Failed to get bookmark by id:" << sqlQuery.lastError().text();
        return item;
    }
    
    if (sqlQuery.next()) {
        item.id = sqlQuery.value(0).toInt();
        item.name = sqlQuery.value(1).toString();
        item.query = sqlQuery.value(2).toString();
        item.created = sqlQuery.value(3).toDateTime();
        item.databaseName = sqlQuery.value(4).toString();
    }
    
    return item;
}

bool BookmarkManager::clearAllBookmarks()
{
    if (!m_initialized) {
        return false;
    }
    
    QSqlQuery sqlQuery(m_database);
    if (!sqlQuery.exec("DELETE FROM bookmarks")) {
        qWarning() << "Failed to clear bookmarks:" << sqlQuery.lastError().text();
        return false;
    }
    
    emit bookmarksChanged();
    return true;
}

int BookmarkManager::bookmarkCount() const
{
    if (!m_initialized) {
        return 0;
    }
    
    QSqlQuery sqlQuery(m_database);
    if (!sqlQuery.exec("SELECT COUNT(*) FROM bookmarks")) {
        qWarning() << "Failed to get bookmark count:" << sqlQuery.lastError().text();
        return 0;
    }
    
    if (sqlQuery.next()) {
        return sqlQuery.value(0).toInt();
    }
    
    return 0;
}

bool BookmarkManager::createTables()
{
    QSqlQuery sqlQuery(m_database);
    QString createTableQuery = R"(
        CREATE TABLE IF NOT EXISTS bookmarks (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            name TEXT NOT NULL,
            query TEXT NOT NULL,
            created DATETIME NOT NULL,
            database_name TEXT
        )
    )";
    
    if (!sqlQuery.exec(createTableQuery)) {
        qWarning() << "Failed to create bookmarks table:" << sqlQuery.lastError().text();
        return false;
    }
    
    // 创建索引以提高查询性能
    QString createIndexQuery = "CREATE INDEX IF NOT EXISTS idx_bookmarks_name ON bookmarks (name)";
    if (!sqlQuery.exec(createIndexQuery)) {
        qWarning() << "Failed to create index on bookmarks table:" << sqlQuery.lastError().text();
        return false;
    }
    
    return true;
}

QString BookmarkManager::getDefaultDatabasePath() const
{
    QString appDataPath = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
    if (appDataPath.isEmpty()) {
        appDataPath = QDir::homePath() + "/.dbtool";
    }
    
    QDir dir(appDataPath);
    if (!dir.exists()) {
        dir.mkpath(appDataPath);
    }
    
    return appDataPath + "/bookmarks.db";
}